home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / apps / sprdshts / viscalc.lzh / VISCALC / SC.C < prev    next >
C/C++ Source or Header  |  1985-11-20  |  19KB  |  855 lines

  1. /*    SC    A Spreadsheet Calculator
  2.  *        Main driver
  3.  *
  4.  *        original by James Gosling, September 1982
  5.  *        modifications by Mark Weiser and Bruce Israel,
  6.  *            University of Maryland
  7.  *
  8.  *              More mods Robert Bond, 12/86
  9.  *        Major mods to run on VMS and AMIGA, 1/17/87
  10.  *
  11.  */
  12.  
  13. #include "sc.h"
  14.  
  15. extern char *malloc();
  16.  
  17. /* default column width */
  18.  
  19. #define DEFWIDTH 10
  20. #define DEFPREC   2
  21.  
  22. #define RESCOL 4  /* columns reserved for row numbers */
  23. #define RESROW 3  /* rows reserved for prompt, error, and column numbers */
  24.  
  25. char curfile[1024];
  26.  
  27. int showme = 1;  /* 1 to display the current cell in the top line */
  28. int batch = 0;
  29.  
  30. error (fmt,a,b,c,d,e) {
  31.     if (batch) fprintf(stderr,fmt,a,b,c,d,e);
  32.     else {
  33.     move (1,0);
  34.     clrtoeol ();
  35.     printw (fmt,a,b,c,d,e);
  36.     }
  37. }
  38.  
  39. int seenerr;
  40.  
  41. yyerror (err)
  42. char *err; {
  43.     if (seenerr) return;
  44.     seenerr++;
  45.     move (1,0);
  46.     clrtoeol ();
  47. #ifdef TOS
  48.     {
  49.         char format[20];
  50.         sprintf(format,"%%s: %%.%ds <= %%s",linelim);
  51.         printw(format,err,line,line+linelim);
  52.     }
  53. #else
  54.     printw ("%s: %.*s <= %s",err,linelim,line,line+linelim);
  55. #endif
  56. }
  57.  
  58. struct ent *
  59. lookat(row,col){
  60.     register struct ent **p;
  61.     if (row < 0)
  62.     row = 0;
  63.     else if (row > MAXROWS-1) 
  64.     row = MAXROWS-1;
  65.     if (col < 0) 
  66.     col = 0;
  67.     else if (col > MAXCOLS-1)
  68.     col = MAXCOLS-1;
  69.     p = &tbl[row][col];
  70.     if (*p==0) {
  71.     *p = (struct ent *) malloc (sizeof (struct ent));
  72.     if (row>maxrow) maxrow = row;
  73.     if (col>maxcol) maxcol = col;
  74.     (*p)->label = 0;
  75.     (*p)->flags = 0;
  76.     (*p)->row = row;
  77.     (*p)->col = col;
  78.     (*p)->expr = 0;
  79.     (*p)->v = (double) 0.0;
  80.     } else if ((*p)->flags & is_deleted) 
  81.     debug("But %s%d has been deleted!", coltoa(col), row);
  82.     return *p;
  83. }
  84.  
  85. /*
  86.  * This structure is used to keep ent structs around before they
  87.  * are deleted to allow the sync_refs routine a chance to fix the
  88.  * variable references.
  89.  * We also use it as a last-deleted buffer for the 'p' command.
  90.  */
  91.  
  92. free_ent(p)
  93. register struct ent *p;
  94. {
  95.     p->next = to_fix;
  96.     to_fix = p;
  97.     p->flags |= is_deleted;
  98. }
  99.  
  100. flush_saved()
  101. {
  102.     register struct ent *p;
  103.     register struct ent *q;
  104.  
  105.     if (!(p = to_fix))
  106.     return;
  107.     while (p) {
  108.     clearent(p);
  109.     q = p->next;
  110.     free(p);
  111.     p = q;
  112.     }
  113.     to_fix = 0;
  114. }
  115.  
  116. update () {
  117.     register    row,
  118.                 col;
  119.     register struct ent **p;
  120.     static  lastmx,
  121.             lastmy;
  122.     static  char *under_cursor = " ";
  123.     int     maxcol;
  124.     int     maxrow;
  125.     int     rows;
  126.     int     cols;
  127.     register r;
  128.  
  129.     while (hidden_row[currow])   /* You can't hide the last row or col */
  130.     currow++;
  131.     while (hidden_col[curcol])
  132.     curcol++;
  133.     if (curcol < stcol)
  134.     stcol = curcol, FullUpdate++;
  135.     if (currow < strow)
  136.     strow = currow, FullUpdate++;
  137.     while (1) {
  138.     register    i;
  139.     for (i = stcol, cols = 0, col = RESCOL;
  140.          (col + fwidth[i]) < COLS-1 && i < MAXCOLS; i++) {
  141.         cols++;
  142.         if (hidden_col[i])
  143.         continue;
  144.         col += fwidth[i];
  145.     }
  146.     if (curcol >= stcol + cols)
  147.         stcol++, FullUpdate++;
  148.     else
  149.         break;
  150.     }
  151.     while (1) {
  152.     register    i;
  153.     for (i = strow, rows = 0, row = RESROW;
  154.          row < ROWS && i < MAXROWS; i++) {
  155.         rows++;
  156.         if (hidden_row[i])
  157.         continue;
  158.         row++;
  159.     }
  160.     if (currow >= strow + rows)
  161.         strow++, FullUpdate++;
  162.     else
  163.         break;
  164.     }
  165.     maxcol = stcol + cols - 1;
  166.     maxrow = strow + rows - 1;
  167.     if (FullUpdate) {
  168.     register int i;
  169.     move (2, 0);
  170.     clrtobot ();
  171.     standout();
  172.     for (row=RESROW, i=strow; i <= maxrow; i++) {
  173.         if (hidden_row[i]) 
  174.         continue;
  175.         move(row,0);
  176. #ifdef TOS
  177.         {
  178.             char format[10];
  179.             sprintf(format,"%%-%dd",RESCOL);
  180.             printw(format,i);
  181.         }
  182. #else
  183.         printw("%-*d", RESCOL, i);
  184. #endif
  185.         row++;
  186.     }
  187.     move (2,0);
  188. #ifdef TOS
  189.     {
  190.         char format[10];
  191.         sprintf(format,"%%%ds",RESCOL);
  192.         printw(format," ");
  193.     }
  194. #else
  195.     printw("%*s", RESCOL, " ");
  196. #endif
  197.     for (col=RESCOL, i = stcol; i <= maxcol; i++) {
  198.         if (hidden_col[i])
  199.         continue;
  200.         move(2, col);
  201. #ifdef TOS
  202.     {
  203.         char format[10];
  204.         sprintf(format,"%%%ds",fwidth[i]);
  205.         printw(format,coltoa(i));
  206.     }
  207. #else
  208.         printw("%*s", fwidth[i], coltoa(i));
  209. #endif
  210.         col += fwidth[i];
  211.     }
  212.     standend();
  213.     }
  214.     for (row = strow, r = RESROW; row <= maxrow; row++) {
  215.     register    c = RESCOL;
  216.     if (hidden_row[row])
  217.         continue;
  218.     for (p = &tbl[row][col = stcol]; col <= maxcol; col++, p++) {
  219.         if (hidden_col[col])
  220.         continue;
  221.         if (*p && ((*p) -> flags & is_changed || FullUpdate)) {
  222.         char   *s;
  223.         move (r, c);
  224.         (*p) -> flags &= ~is_changed;
  225.         if ((*p) -> flags & is_valid)
  226. #ifdef TOS
  227.             {
  228.                 char format[16];
  229.                 sprintf(format,"%%%d.%df",fwidth[col],precision[col]);
  230.                 printw(format,(*p)->v);
  231.             }
  232. #else
  233.             printw ("%*.*f", fwidth[col], precision[col], (*p) -> v);
  234. #endif
  235.         if (s = (*p) -> label) {
  236.             char field[1024];
  237.  
  238.             strncpy(field,s,fwidth[col]);
  239.             field[fwidth[col]] = 0;
  240.             move (r,(*p) -> flags & is_leftflush
  241.                 ? c : c - strlen (field) + fwidth[col]);
  242.             addstr(field);
  243.         }
  244.         }
  245.         c += fwidth[col];
  246.     }
  247.     r++;
  248.     }
  249.     
  250.     move(lastmy, lastmx);
  251.     if (inch() == '<')
  252.         addstr (under_cursor);
  253.     lastmy =  RESROW;
  254.     for (row = strow; row < currow; row++)
  255.     if (!hidden_row[row])
  256.         lastmy += 1;
  257.     lastmx = RESCOL;
  258.     for (col = stcol; col <= curcol; col++)
  259.     if (!hidden_col[col])
  260.         lastmx += fwidth[col];
  261.     move(lastmy, lastmx);
  262.     *under_cursor = inch();
  263.     addstr ("<");
  264.     move (0, 0);
  265.     clrtoeol ();
  266.     if (linelim >= 0) {
  267.     addstr (">> ");
  268.     addstr (line);
  269.     } else {
  270.     if (showme) {
  271.         register struct ent *p;
  272.         p = tbl[currow][curcol];
  273.         if (p && ((p->flags & is_valid) || p->label)) {
  274.         if (p->expr || !p->label) {
  275.             linelim = 0;
  276.             editexp(currow, curcol);
  277.         } else {
  278.             sprintf(line, "%s", p->label);
  279.         }
  280.         addstr("[");
  281.         addstr (line);
  282.         addstr("]");
  283.         linelim = -1;
  284.         } else {
  285.         addstr("[]");
  286.         }
  287.     }
  288.     move (lastmy, lastmx);
  289.     }
  290.     FullUpdate = 0;
  291. }
  292.  
  293. void
  294. quit()
  295. {
  296.     endwin ();
  297.     exit();
  298. }
  299.  
  300. main (argc, argv)
  301. char  **argv; {
  302.     int     inloop = 1;
  303.     register int   c;
  304.     int     edistate = -1;
  305.     int     arg = 1;
  306.     int     narg;
  307.     int     nedistate = -1;
  308.     int        running = 1;
  309.     {
  310.     register    i;
  311.     for (i = 0; i < MAXCOLS; i++) {
  312.         fwidth[i] = DEFWIDTH;
  313.         precision[i] = DEFPREC;
  314.     }
  315.     }
  316.     linelim = -1;
  317.     curfile[0]=0;
  318.     running = 1;
  319.  
  320.     if (argc > 1 && (! strcmp(argv[1],"-b"))) {
  321.     argc--, argv++;
  322.     batch = 1;
  323.     }
  324.  
  325.     if (! batch) {
  326.     initscr ();
  327.     }
  328.     initkbd();
  329.     if (argc > 1) {
  330.     strcpy(curfile,argv[1]);
  331.     readfile (argv[1],0);
  332.     }
  333.     modflg = 0;
  334.     if (batch) exit(0);
  335.     error ("VC 2.1  Type '?' for help.");
  336.     FullUpdate++;
  337.     while (inloop) { running = 1;
  338.     while (running) {
  339.     nedistate = -1;
  340.     narg = 1;
  341.     if (edistate < 0 && linelim < 0 && (changed || FullUpdate))
  342.         EvalAll (), changed = 0;
  343.     update ();
  344.     refresh ();
  345.     move (1, 0);
  346.     clrtoeol ();
  347.     fflush (stdout);
  348.     seenerr = 0;
  349.     if (((c = nmgetch ()) < ' ') || ( c == 0177 ))
  350.         switch (c) {
  351.         case ctl (z):
  352.             quit();
  353.             break;
  354.         case ctl (r):
  355.             FullUpdate++;
  356.             touchwin();
  357.             clear();
  358.             break;
  359.         default:
  360.             error ("No such command  (^%c)", c + 0100);
  361.             break;
  362.         case ctl (b):
  363.             while (--arg>=0) {
  364.             if (curcol)
  365.                 curcol--;
  366.             else
  367.                 error ("At column A");
  368.             while(hidden_col[curcol] && curcol)
  369.                 curcol--;
  370.             }
  371.             break;
  372.         case ctl (c):
  373.             running = 0;
  374.             break;
  375.         case ctl (f):
  376.             while (--arg>=0) {
  377.             if (curcol < MAXCOLS - 1)
  378.